﻿using System;
using System.Text;
using RAP.Framework.Libary.Utils;
using RAP.Framework.Libary.DomTemplateBuilder.Element;
using RAP.Framework.Libary.DomTemplateBuilder.Configuration;
using RAP.Framework.Libary.DomTemplateBuilder.Interface;

namespace RAP.Framework.Libary.DomTemplateBuilder.Handler
{
	/// <summary>
	/// 动态引用配置的Handler
	/// </summary>
	public class EvalTemplateHandler : HandlerBase
	{
		public override void DoRender ( StringBuilder writer, object rootParamObject, object parentParamObject, ITemplateRenderContext context )
		{
			var ele = this.Element as EvalTemplate;
			var elseEle = ele.Else;
			var paramObj = this.GetParamObject ( rootParamObject, parentParamObject, context );
			var result = string.Empty;
			var fullName = string.Empty;

			var sbFullName = new StringBuilder ( );
			base.DoRender ( sbFullName, rootParamObject, parentParamObject, context );
			fullName = sbFullName.ToString ( ).Trim ( );
			var tplItem = TemplateItem.FindTemplate ( ele.Template, fullName );
			if ( tplItem != null )
			{
				//如果存在指定名称局部子模板，则直接调用子模板
				result = TemplateItem.DoRender ( tplItem, rootParamObject, paramObj, context );
			}
			else
			{
				//调用全局模板
				if ( fullName.IndexOf ( '.' ) < 0 )
				{
					fullName = string.Format ( "{0}.{1}", ele.Template.DomTemplate.NameSpace, fullName );
				}
				if ( elseEle != null )
				{
					//如果存在Else节点，则判断指定模板是否存在
					if ( DomTemplateManager.Instance.HasTemplate ( fullName ) )
					{
						//如果存在则执行模板
						if ( TemplateItem.CheckTemplateAccessable ( this.Element.Template, fullName ) )
						{
							result = DomTemplateManager.Instance.RunTemplate ( fullName, rootParamObject, paramObj, context );
						}
						else
						{
							throw new Exception ( string.Format ( "访问者模板：{0} 不能访问模板：{1}。", ele.Template.FullName, fullName ) );
						}
					}
					else
					{
						//执行否则节点的逻辑
						elseEle.Handler.DoRender ( writer, rootParamObject, paramObj, context );
					}
				}
				else
				{
					//如果不存在Else节点，则执行模板
					try
					{
						result = DomTemplateManager.Instance.RunTemplate ( fullName, rootParamObject, paramObj, context );
					}
					catch ( Exception e )
					{
						if ( ele.ThrowError )
						{
							throw e;
						}
					}
				}
			}
			if ( result.IsNotNullOrEmpty ( ) )
			{
				writer.Append ( result );
			}
		}
	}
}
